module Data.Transform.Meta where


import Data.Map as Map hiding (split)
import Control.Monad.State


--import Data.Transform.Type
import Data.Transform.Coupled


place =       Tag "Place" String
transmition = Tag "Transmition" String
net =         Tag "Net" String
color =       Tag "Color" String

petri1 = Prod (Map (Prod place transmition) One)
              (Prod (Map transmition net)
                    (Prod (Map place net)
                          (Prod (Map transmition One)
                                (Tag "PlaceDef" (Map place One)))))

-- added a property to PlaceDef
petri2 = Prod (Map (Prod place transmition) One)
              (Prod (Map transmition net)
                    (Prod (Map place net)
                          (Prod (Map transmition One)
                                (Tag "PlaceDef" (Map place (Prod One color))))))


petriNet1 = (Map.fromList [(("place1", "transmition1"), ())],
              (Map.fromList [("transmition1", "net1")],
                (Map.fromList [("place1", "net1")],
                  (Map.fromList [("transmition1", ())], 
                   Map.fromList [("place1", ())]))))

petriNet2  = (Map.fromList [(("place1","transmition1"),())],
               (Map.fromList [("transmition1","net1")],
                 (Map.fromList [("place1","net1")],
                   (Map.fromList [("transmition1",())], Map.fromList [("place1",((),"white"))]))))

{-
testPN1 =
  do
  -- forth
    let Just petri1' = once (inside "PlaceDef" (addProperty1 (Tag "Color" String) "white")) petri1
    let Just petriNet1' = forth petri1' petri2 petriNet1
    --putStrLn $ gshow petri2 petriNet1'
    putStrLn $ "new value (forth): \n" ++ show petriNet1'
  -- back
    let Just petriNet1'' = back petri1' petri2 petriNet2
    putStrLn $ "first value again (back): \n" ++ show petriNet1''
-}

{-
*Data.Transform.Meta> testPN1
new value (forth): 
(fromList [(("place1","transmition1"),())],(fromList [("transmition1","net1")],(fromList [("place1","net1")],(fromList [("transmition1",())],fromList [("place1",((),"white"))]))))
first value again (back): 
(fromList [(("place1","transmition1"),())],(fromList [("transmition1","net1")],(fromList [("place1","net1")],(fromList [("transmition1",())],fromList [("place1",())]))))
-}


{-
*Data.Transform.Meta> ((once (inside "PlaceDef" (addProperty1 (Tag "Color" String) "white")))) petri1
Just (View (Rep <to> <from>) (Prod (Map (Prod (Tag "Place" String) (Tag "Transmition" String)) One) (Prod (Map (Tag "Transmition" String) (Tag "Net" String)) (Prod (Map (Tag "Place" String) (Tag "Net" String)) (Prod (Map (Tag "Transmition" String) One) (Tag "PlaceDef" (Map (Tag "Place" String) (Prod One (Tag "Color" String)))))))))
-}

{-
addProperty1 :: Type c -> c -> Rule
addProperty1 ct c (Map a b) = return $ View rep (Map a (Prod b ct))
  where
    rep = Rep {to = MAP (SPLIT ID (pnt c)), from = MAP FST}

addProperty1 _ _ _ = mzero
-}
